#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     loadbalance_chanel
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/12/20
-------------------------------------------------
   修改描述-2021/12/20:         
-------------------------------------------------
"""
import abc
import random


class AbstractLoadBalance(metaclass=abc.ABCMeta):

    def select(self, service_list):
        '''
        从服务节点列表选择一个节点信息返回，客户端从注册中心列表的时候返回服务节点信息
        :param service_list:
        :return:
        '''
        if not isinstance(service_list, list):
            raise Exception("Invalid para, service_list must is list")

        if not len(service_list):
            return None

        if len(service_list) == 1:
            return service_list[0]

        return self.do_select(service_list)

    @abc.abstractmethod
    def do_select(self, service_list):
        pass

    @abc.abstractmethod
    def _get_weight(self, one_service):
        return random.randint(1, 10)

class RandomLoadBalance(AbstractLoadBalance):

    def do_select(self, service_list):
        all_weight_equal = True
        total_weights = 0
        # 根据返回列表进行权重列表的配置处理
        weigths_list = [self._get_weight(service) for service in service_list]
        # 处理枚举列表
        for index, weight in enumerate(weigths_list):
            total_weights += weight
            if all_weight_equal and (index > 0) and (weight != weigths_list[index - 1]):
                all_weight_equal = False

        if total_weights > 0 and not all_weight_equal:
            offset = random.randint(1, total_weights)

            for index, weight in enumerate(weigths_list):
                offset = weight - offset
                if offset < 0:
                    return service_list[index]

        return random.choice(service_list)